/*
 * Copyright (C) 2008 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.megagoodsoftware.MediaShare;

import java.util.ArrayList;
import java.util.Random;

import android.app.Activity;
import android.app.Dialog;
import android.app.NotificationManager;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.widget.BaseAdapter;
import android.widget.CheckBox;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.LinearLayout;

import com.github.droidfu.adapters.WebGalleryAdapter;
import com.megagoodsoftware.smugmug.Constants;
import com.megagoodsoftware.smugmug.Photo;
import com.megagoodsoftware.smugmug.PhotoList;
import com.megagoodsoftware.smugmug.PhotoSize;
import com.megagoodsoftware.smugmug.SmugMug;
import com.megagoodsoftware.smugmug.SmugMugAlbum;
import com.megagoodsoftware.smugmug.exceptions.SmugMugFailedResponse;
import com.megagoodsoftware.smugmug.exceptions.SmugMugInternalError;


/**
 * Activity used to display a SmugMug user's photos. This activity shows all the photos
 * for one album in one gridview. The activity is invoked either by LoginActivity, when
 * the application is launched normally, or by a Home shortcut, or by an Intent with
 * the view action and a flickr://photos/nsid URI.
 */
public class SmugMugPhotostreamActivity extends Activity implements
        View.OnClickListener {

    static final String ACTION = "com.megagoodsoftware.MediaShare.FLICKR_VIEW_STREAM";

    static final String EXTRA_NOTIFICATION = "com.megagoodsoftware.MediaShare.extra_notify_id";
    static final String EXTRA_NSID = "com.megagoodsoftware.MediaShare.extra_nsid";
    static final String EXTRA_USER = "com.megagoodsoftware.MediaShare.extra_user";

    private static final String STATE_USER = "com.megagoodsoftware.MediaShare.state_user";
    private static final String STATE_PAGE = "com.megagoodsoftware.MediaShare.state_page";
    private static final String STATE_PAGE_COUNT = "com.megagoodsoftware.MediaShare.state_pagecount";
    private static final String STATE_ALBUM = "com.megagoodsoftware.MediaShare.state_album";

    private static final int PHOTOS_COUNT_PER_PAGE = 0;


    private User mUser;
    private int mCurrentPage = 0;
    private int mPageCount = 0;

    private AsyncTask<?, ?, ?> mTask;
    private String mUsername;
	private SmugMug sm;
	private SmugMugAlbum mAlbum;
	private String mAlbumName;
    private ImageAdapter mAdapter;
	private ArrayList<LoadedPhoto> mThumbIds;
    private PhotoList mImageList;
	private FlingGallery mGallery;
	private WebGalleryAdapter wAdapter;
	
	@Override
    public boolean onTouchEvent(MotionEvent event)
	{
        return mGallery.onGalleryTouchEvent(event);
    }

    
	@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
		Log.i(Constants.TAG,"onCreate called.");

        clearNotification();

        // Try to find a user name in the saved instance state or the intent
        // that launched the activity. If no valid user NSID can be found, we
        // just close the activity.
        if (!initialize(savedInstanceState)) {
            finish();
            return;
        }
 
		mThumbIds = new ArrayList<LoadedPhoto>();

		setContentView(R.layout.main);

		GridView gridview = (GridView) findViewById(R.id.gridview);
		mAdapter = new ImageAdapter(this);
		gridview.setAdapter(mAdapter);

        sm = ((MediaShareApp) getApplicationContext()).getSmugMugHandle();
		mAlbum = sm.getAlbums(mAlbumName).get(0);

    	mTask = new SmugMugLoginTask().execute();
    }

	@Override
	protected void onResume() {
		super.onResume();
		Log.i(Constants.TAG,"onResume() called!");
		Log.i(Constants.TAG,"onResume() mCurrentPage is: " + mCurrentPage + "!");
        if (mTask == null) {  // should be !null in most cases
    		Log.i(Constants.TAG,"onResume() mTask was null!");
        	loadPhotos();
        }

	}
	
	@Override
	protected void onPause() {
		super.onPause();
		Log.i(Constants.TAG,"onPause() called!");
		Log.i(Constants.TAG,"onPause() mCurrentPage is: " + mCurrentPage + "!");
		if (mTask != null) {
			Log.i(Constants.TAG,"mTask.getStatus() is: " + mTask.getStatus() + "!");
        if (mTask.getStatus() == AsyncTask.Status.RUNNING) {
            mTask.cancel(true);
        }
		}
        mTask = null;
	}
	
	@Override
	protected Dialog onCreateDialog(int id) {
		switch(id) {
		case 0: {
			ProgressDialog dialog = new ProgressDialog(this);
			dialog.setMessage("Accessing " + mAlbum.getTitle() + " ...");
			dialog.setIndeterminate(true);
			dialog.setCancelable(true);
			return dialog;
		}
		}
		return null;
	}

   private void clearNotification() {
//        final int notification = getIntent().getIntExtra(EXTRA_NOTIFICATION, -1);
//        if (notification != -1) {
//            NotificationManager manager = (NotificationManager)
//                    getSystemService(Context.NOTIFICATION_SERVICE);
//            manager.cancel(notification);
//        }
    }

    /**
     * Starts the PhotostreamActivity for the specified user.
     *
     * @param context The application's environment.
     * @param string The user whose photos to display with a PhotostreamActivity.
     */
    static void show(Context context, String string) {
        final Intent intent = new Intent(ACTION);

        intent.putExtras(((Activity) context).getIntent());
        intent.putExtra(SmugMugBundleHelper.EXTRA_ALBUM, string);
        context.startActivity(intent);
    }

    /**
     * Restores a previously saved state or, if missing, finds the user's NSID
     * from the intent used to start the activity.
     *
     * @param savedInstanceState The saved state, if any.
     *
     * @return true if a {@link com.google.android.photostream.Flickr.User} was
     *         found either in the saved state or the intent.
     */
    private boolean initialize(Bundle savedInstanceState) {
        User user;
        if (savedInstanceState != null) {
            user = savedInstanceState.getParcelable(STATE_USER);
            //mCurrentPage = savedInstanceState.getInt(STATE_PAGE);
            mPageCount = savedInstanceState.getInt(STATE_PAGE_COUNT);
            mAlbumName = savedInstanceState.getString(STATE_ALBUM);
        } else {
            final Intent intent = getIntent();

            user = SmugMugBundleHelper.getUserFromBundle(intent);
            mAlbumName = SmugMugBundleHelper.getAlbumFromBundle(intent);
        }
        mUser = user;
        return (mUser != null && mAlbumName != null)|| mUsername != null;
    }


    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);

		Log.i(Constants.TAG,"onSaveInstanceState called.");

		outState.putParcelable(STATE_USER, mUser);
        outState.putInt(STATE_PAGE, mCurrentPage);
        outState.putInt(STATE_PAGE_COUNT, mPageCount);
        outState.putString(STATE_ALBUM, mAlbumName);
        removeDialog(0);
        //outState.putParcelable(STATE_ACCOUNT, sm.getAccount());
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
		Log.i(Constants.TAG,"onDestroy called.");

    }

    public void onClick(View v) {
        switch (v.getId()) {
            default:
                onShowPhoto((Photo) v.getTag());
                break;
        }
    }

    class NonConfigInstanceData {
    	LoadedPhoto[] list;
    	PhotoList pList;
    }
    
    @Override
    public Object onRetainNonConfigurationInstance() {
        final GridView grid = (GridView) findViewById(R.id.gridview);
        final int count = grid.getChildCount();
        final LoadedPhoto[] list = new LoadedPhoto[count];
        final NonConfigInstanceData data = new NonConfigInstanceData();
 

        for (int i = 0; i < count; i++) {
            final ImageView v = (ImageView) grid.getChildAt(i);
            list[i] = new LoadedPhoto(((BitmapDrawable) v.getDrawable()).getBitmap(),
                    (Photo) v.getTag());
        }
        data.list = list;
        data.pList = mImageList;
        if (mImageList == null) {
        	Log.i(Constants.TAG,"onRetainNonConfigInstance called, mImageList is NULL!");
        } else {
        	Log.i(Constants.TAG,"onRetainNonConfigInstance called, loaded photos list size: "
				+ list.length + " mImageList length: " +
				mImageList.getCount());
        }
       return data;
    }

    private class SmugMugLoginTask extends AsyncTask<Void, Void, Void> {

        @Override
        public void onPreExecute() {
			Log.i(Constants.TAG, "SMLoginTask: Showing Dialog");
			showDialog(0);
        }

		@Override
		public Void doInBackground(Void... params) {
			try {

				Log.i(Constants.TAG, "SMLoginTask: Updating Album Cache");
				sm.updateCache(mAlbum);
			} catch (SmugMugInternalError e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (SmugMugFailedResponse e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			return null;
		}

		@Override
		public void onPostExecute(Void input) {
			mTask = null;
			Log.i(Constants.TAG, "SMLoginTask: Done");
			dismissDialog(0);
			getPhotoList();
            
		}
    }
    
    private void getPhotoList() {
    	mTask = new GetPhotoListTask().execute(mCurrentPage);
    }
    
	private void loadPhotos() {
		Object data = getLastNonConfigurationInstance();
		if (data != null) {
			NonConfigInstanceData foo = (NonConfigInstanceData) data;
			PhotoList bar = (PhotoList) foo.pList;
			final LoadedPhoto[] d = (LoadedPhoto[]) foo.list;
			if (bar.getCount() == 0 && d.length == 0) {
				data = null;
			}
		}
		if (data != null) {
			Log.i(Constants.TAG, "loadPhoto() - nonConfigData is not null");
			final LoadedPhoto[] photos = (LoadedPhoto[]) data;
			for (LoadedPhoto photo : photos) {
				addPhoto(photo);
			}
		}
		showPhotos(mImageList);
		// prepareMenu(mPageCount);
		// mSwitcher.showNext();
	}

    private void showPhotos(PhotoList photos) {
        mTask = new LoadPhotosTask().execute(photos);
    }

    private void onShowPhoto(Photo photo) {
        if (mTask != null && mTask.getStatus() == AsyncTask.Status.RUNNING) {
            mTask.cancel(true);
        }
       ViewPhotoActivity.show(this, photo);
    }

    private void addPhoto(LoadedPhoto... value) {
        mThumbIds.add(value[0]);
        mAdapter.notifyDataSetChanged();
    }    

    /**
     * Background task used to load each individual photo. The task loads each photo
     * in order and publishes each loaded Bitmap as a progress unit. The tasks ends
     * by hiding the progress bar and showing the menu.
     */
    private class LoadPhotosTask extends AsyncTask<PhotoList, LoadedPhoto, PhotoList> {
        private final Random mRandom;

        private LoadPhotosTask() {
            mRandom = new Random();
        }

        public PhotoList doInBackground(PhotoList... params) {
            final PhotoList list = params[0];
            final int count = list.getCount();
    		Log.i(Constants.TAG,"LoadPhotosTask count is " + count);

            // mCurrentPage is really current image
            for (int i = mCurrentPage; i < count; i++) {
                if (isCancelled()) break;

                final Photo photo = list.get(i);
                Log.i(Constants.TAG, "Loading photo: " + i);
                Bitmap bitmap = photo.loadPhotoBitmap(PhotoSize.THUMBNAIL);
                if (!isCancelled()) {
                    if (bitmap == null) {
                        final boolean portrait = mRandom.nextFloat() >= 0.5f;
                        bitmap = BitmapFactory.decodeResource(getResources(), portrait ?
                            R.drawable.not_found_small_1 : R.drawable.not_found_small_2);
                    }
                    publishProgress(new LoadedPhoto(ImageUtilities.rotateAndFrame(bitmap), photo));
                    bitmap.recycle();
                    mCurrentPage++;
                }
            }

            return list;
        }

        /**
         * Whenever a photo's Bitmap is loaded from the background thread, it is
         * displayed in this method by adding a new ImageView in the photos grid.
         * Each ImageView's tag contains the {@link com.megagoodsoftware.smugmug.google.android.photostream.Flickr.Photo}
         * it was loaded from.
         *
         * @param value The photo and its bitmap.
         */
        @Override
        public void onProgressUpdate(LoadedPhoto... value) {
            addPhoto(value);
        }

        @Override
        public void onPostExecute(PhotoList result) {
            mPageCount = result.getPageCount();
            //prepareMenu(mPageCount);
            //mSwitcher.showNext();
            mTask = null;            
        }
    }

    /**
     * Background task used to load the list of photos. The tasks queries Flickr for the
     * list of photos to display and ends by starting the LoadPhotosTask.
     */
    private class GetPhotoListTask extends AsyncTask<Integer, Void, PhotoList> {

		@Override
        public void onPreExecute() {
            //showProgress();
        }

        public PhotoList doInBackground(Integer... params) {
        	return mAlbum.getImages(PHOTOS_COUNT_PER_PAGE, params[0]);
        }

        @Override
        public void onPostExecute(PhotoList photoList) {
        	//hideProgress();
        	mImageList = photoList;
            mTask = null;
			Log.i(Constants.TAG, "GetPhotoListTask: Done");
			((MediaShareApp) getApplicationContext()).setPhotoList(mImageList);
	        loadPhotos();
        }
    }

    /**
     * A LoadedPhoto contains the Flickr photo and the Bitmap loaded for that photo.
     */
    private static class LoadedPhoto {
        Bitmap mBitmap;
        Photo mPhoto;

        LoadedPhoto(Bitmap bitmap, Photo photo) {
            mBitmap = bitmap;
            mPhoto = photo;
        }
    }
    
	public class ImageAdapter extends BaseAdapter {
		private Context mContext;

		public ImageAdapter(Context c) {
			mContext = c;
		}

		public int getCount() {
			return mThumbIds.size();
		}

		public Object getItem(int position) {
			return null;
		}

		public long getItemId(int position) {
			return 0;
		}

		// create a new ImageView for each item referenced by the Adapter
		public View getView(int position, View convertView, ViewGroup parent) {
			ImageView imageView;
			if (convertView == null) { // if it's not recycled, initialize some
										// attributes
//		        ImageView image = (ImageView) mInflater.inflate(R.layout.grid_item_photo, mGrid, false);
		 				imageView = new ImageView(mContext);
//				imageView.setLayoutParams(new GridView.LayoutParams(85, 85));
				imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
				imageView.setPadding(8, 8, 8, 8);
			} else {
				imageView = (ImageView) convertView;
			}

			imageView.setTag(mThumbIds.get(position).mPhoto);
			imageView.setOnClickListener(SmugMugPhotostreamActivity.this);
			imageView.setImageBitmap(mThumbIds.get(position).mBitmap);
			return imageView;
		}

	}
}
